// converter_encrypted.js
const ffmpeg = require("fluent-ffmpeg")
const fs = require("fs")
const path = require("path")
const crypto = require("crypto")

// 输入输出路径设置
const filename = "input3.mp4"
const input = path.resolve(__dirname, filename)
const output = path.resolve(
  __dirname,
  "../public",
  "encrypted",
  filename.replace(path.extname(filename), "")
)

/**
 * 调用转换
 */
convertToEncryptedHLS(input, output)
  .then(res => {
    console.log(res)
  })
  .catch(err => {
    console.error(err.message)
  })

// 生成16字节的随机密钥
function generateEncryptionKey(keyPath) {
  const key = crypto.randomBytes(16)
  fs.writeFileSync(keyPath, key)
  return key
}

// 创建密钥信息文件
function createKeyInfoFile(keyInfoPath, keyUri, keyPath, iv = null) {
  const ivString = iv ? iv.toString("hex") : ""
  const keyInfoContent = `${keyUri}\n${keyPath}\n${ivString}`
  fs.writeFileSync(keyInfoPath, keyInfoContent)
  return keyInfoPath
}

function convertToEncryptedHLS(inputPath, outputDir) {
  return new Promise((resolve, reject) => {
    // 检查输入文件是否存在
    if (!fs.existsSync(inputPath)) {
      reject(new Error(`输入文件不存在: ${inputPath}`))
      console.log(`输入文件不存在: ${inputPath}`)
      return
    }

    // 确保输出目录存在
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true })
      console.log("输出目录创建成功")
    }

    // 生成密钥和密钥信息文件
    const keyName = "encryption.key"
    const keyPath = path.join(outputDir, keyName)
    generateEncryptionKey(keyPath)
    console.log(`加密密钥已生成: ${keyPath}`)

    const keyInfoPath = path.join(outputDir, "enc_key_info.keyinfo")
    createKeyInfoFile(keyInfoPath, keyName, keyPath)
    console.log(`密钥信息文件已创建: ${keyInfoPath}`)

    console.log(`开始加密转换: ${inputPath} -> ${outputDir}`)

    ffmpeg(inputPath)
      .videoCodec("libx264")
      .audioCodec("aac")
      .outputOptions([
        "-hls_time 10", // 分段时间
        "-hls_list_size 0", // 包含所有分段
        `-hls_segment_filename ${outputDir}/segment_%03d.ts`, // 分段名
        `-hls_key_info_file ${keyInfoPath}`, // 密钥信息文件
        "-hls_playlist_type vod", // 点播类型
        "-f hls" // 转换格式
      ])
      .output(`${outputDir}/index.m3u8`)
      .on("start", commandLine => {
        console.log("FFmpeg命令:", commandLine)
      })
      .on("progress", progress => {
        if (progress.percent) {
          console.log(`转换进度: ${Math.round(progress.percent)}%`)
        }
      })
      .on("stderr", stderrLine => {
        // console.log("FFmpeg输出:", stderrLine);
      })
      .on("end", () => {
        console.log("加密转换完成!")
        console.log("注意: 请确保在服务器上正确配置密钥文件的访问权限")
        resolve(`${outputDir}/index.m3u8`)
      })
      .on("error", (err, stdout, stderr) => {
        console.error("加密转换失败:", err.message)
        reject(err)
      })
      .run()
  })
}
